

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.zip.GZIPInputStream;



public class Gprobs
{
	
	
	public static void main(String[] args) 
	{
		
		 try{
			  String strLine,tmp,substring,javapath,tempfile,tempsh;
			  List elements = null;
			  int count,num_line=1,prev_count=0,ret_line=0;
			  int idx;
			  File f1=null;
			  BufferedReader br=null;
			  DataInputStream in=null;
			  GZIPInputStream gz=null;
			  //checking arguments
			  if(args.length==0 ||args.length !=5 || args[0].equals("-h") || args[0].equalsIgnoreCase("-help"))
			  {
				  System.out.println(" <INPUT TO GPROBS> <PATH TO TEMP DIRECTORY> <PATH TO GRPOBS METRIC JAR FILE> <MEMORY IN M FOR THE GPROBS JAR> <OUTPUTFILE>");
				  System.exit(1);
			   
			  }
			  
			  if(!args[3].matches("^\\d+$"))
			  {
				  System.out.println("Memory required should be numbers");
				  System.exit(1);
			  }
			  f1 = new File(args[0]);
			  if(!f1.exists()) 
			  { 
				  System.out.println("PARAMETER1 : Input Gprobs file doesn't exists ");
				  System.exit(1);
			  
			  }
			  
			  f1 = new File(args[2]);
			  if((!f1.exists()) || !(args[2].matches("^.*jar$"))) 
			  { 
				  System.out.println("PARAMETER3: Input Gprobs Metrics jar file doesn't exist and should end with jar ");
				  System.exit(1);
			  
			  }
			  //checking temp directory exist if not creating one
			  f1=new File(args[1]);
			  if(!f1.exists()) 
			  { 
				  new File(args[1]).mkdir();
			  
			  }
			  //temp files
			  tempfile=args[1]+"/"+"temp.txt";
			  tempsh =args[1]+"/"+"temp.sh";
			  javapath=" | /usr/java/latest/bin/java -Xmx"+args[3]+"m -jar ";
			  substring=" -9";
			  // command line parameter
			  FileInputStream fstream = new FileInputStream(args[0]);
			  if(args[0].matches("^.*gz$"))
			 {		  
			  gz = new GZIPInputStream(fstream);
			  in = new DataInputStream(gz);
			 }
			  else
			  {
			  
			  in = new DataInputStream(fstream);
			   
			  }
			 
			  br = new BufferedReader(new InputStreamReader(in)); 
			  //creating the temp file
			  BufferedWriter bw = new BufferedWriter(new FileWriter(tempfile));
			  //creating the output file
			  BufferedWriter bout = new BufferedWriter(new FileWriter(args[4]));
			  bout.close();
			  // Get the object of DataInputStream
			  
			  //Read Header Line
			  tmp = br.readLine();
			  elements=Arrays.asList(tmp.split(" "));
			  String[] elem = new String[elements.size()];
			//Read File Line By Line
			  while ((strLine = br.readLine()) != null)   
			  {
				 
					  // while loop starts
					  num_line++;
					  elem=strLine.split(" ");
					  
					  //checking the number of columns should be multiple of 3
					  if(elem.length  != elements.size())
					  {
					  	  System.out.println("some thing wrong with number of missing values Linenumber " +num_line);
					  	  System.exit(1);
					   }	
					  count = 0;
					  idx=0;
					  //counting number of missing
					  while ((idx = strLine.indexOf(substring, idx)) != -1)
					  {
						  	idx++;
					        count++;
					  }
					  //checking the number missing should be multiple of 3
					  if(count%3 != 0)
					  {
						  System.out.println("some thing wrong with number of missing values Linenumber " +num_line+ " number of missing "+count);
						  System.exit(1);
					  }
					  //writing the header to the temp file if nothing is wrong with first line
					  if(count == prev_count && num_line == 2)
					  {
							bw.write(tmp);
							bw.newLine();
					  }	
					  //System.out.println(strLine +" count "+count+" prevcount "+prev_count);
					  //if missing data occurs
					  if(count != prev_count)
					  {
						  //closing the temp file
						  bw.close();
						  //creating the bash command to run the Gprobs
						  tmp="cat "+tempfile+javapath+args[2];
						  //running the gprobs on the temp file
						  if(num_line != 2)
						  {  
								
								ret_line=ret_line+runGprobs(tmp,tempsh,args[4],tempfile);
						  }
						  //recraeting the temp file
						  bw = new BufferedWriter(new FileWriter(tempfile));
						  tmp="marker alleleA alleleB";
						  for(int i=1;i<=elements.size()-count-3;i++)
						  {
							  tmp=tmp+" "+i+" "+i+" "+i;
							  i++;
							  i++;
						  }
						  bw.write(tmp);
						  bw.newLine();
					  }  
					  tmp=strLine.replace(substring, "");
					  bw.write(tmp);
					  bw.newLine();
					    //continue
					  prev_count=count;
					  //while loop ends
			  }  
			  //creating the bash command to run the Gprobs
			  tmp="cat "+tempfile+javapath+args[2];
			  //Close the input stream
			  if(args[0].matches("^.*gz$"))
				 {
				  gz.close();
			   in.close();
				 }
			  else
			  {
				  in.close();  
			  }
			  bw.close();
			   
			  //running the gprobs on the temp file
			  ret_line=ret_line+runGprobs(tmp,tempsh,args[4],tempfile);
			  //deleting the temp file
			  //f1 = new File(tempfile);
			  //f1.delete();
			  //f1 = new File(tempsh);
			  //f1.delete();
			  //f1 = new File(args[1]);
			  //f1.delete();
			  
			  if(ret_line != num_line-1)
			  {
				  f1 = new File(args[4]);
				  f1.delete();
				  throw new Exception("Input number of lines not equal to output number of lines .Program unsuccessful");
			    	//System.out.println("Input number of lines not equal to output number of lines .Program unsuccessful");
					//System.exit(1);
			  }
			}
		 	catch (Exception e)
		 	{	
		 		//Catch exception if any
		 		System.err.println("Error: " + e.getMessage());
			  
			}
		 
	}
	static int runGprobs(String x,String tempsh,String out,String tempfile)
	{
		//creating the sting array to run the bash command
		 
		//System.exit(1);
		String x1="sh "+tempsh;
		int num=0;
		try
		{
			BufferedWriter bout = new BufferedWriter(new FileWriter(out,true));
			//opening the temp file to chck for empty lines
			BufferedReader br = new BufferedReader(new InputStreamReader(new DataInputStream(new FileInputStream(tempfile)))); 
			 //Read Header Line
			String tmp = br.readLine();
			List elements=Arrays.asList(tmp.split(" "));
			if(elements.size() == 3)
			{
				String[] elem = new String[elements.size()];
				//Read File Line By Line
				  while ((tmp = br.readLine()) != null)   
				  {	  num++;
					  elem=tmp.split(" ");
					  bout.write(elem[0]+"\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL");
					  bout.newLine();
				  } 
				
				br.close();
			}
			else
			{	
				//opening the temp sh file
				BufferedWriter bw = new BufferedWriter(new FileWriter(tempsh));
				bw.write(x);
				bw.newLine();
				bw.close();
				//redirecting the bash output
				Process p=Runtime.getRuntime().exec(x1);
				//p.waitFor();
				BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
				String line=reader.readLine();
				while(line!=null)
				{
					num++;
					//System.out.println(line);
					bout.write(line);
					bout.newLine();
					line=reader.readLine();
				}
				reader.close();
			}
			bout.close();
		}
		catch(IOException e1) 
		{
			System.err.println("Error: " + e1.getMessage());
		}
		return num;
		}
}
	


